package com.freexiaoyu.freevideoplay;

import android.app.Activity;
import android.media.MediaCodec;
import android.media.MediaCodecInfo;
import android.media.MediaFormat;
import android.os.Build;
import android.os.Bundle;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import com.freexiaoyu.freevideoplay.utils.CommonUtil;

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;

public class VideoStreamPlayerActivity extends Activity implements SurfaceHolder.Callback {

    private MediaCodec mediaCodec;
    private SurfaceHolder surfaceHolder;
    private ServerSocket serverSocket;
    private Socket clientSocket;
    MediaFormat mediaFormat;
    SurfaceView surfaceView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_video_play);
        surfaceView = findViewById(R.id.surfaceView);
        surfaceHolder = surfaceView.getHolder();
        surfaceHolder.addCallback(this);

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    serverSocket = new ServerSocket(22001);
                    clientSocket = serverSocket.accept(); // 这里应该在一个单独的线程中运行以避免阻塞UI线程
                    startDecoding(clientSocket.getInputStream());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }


    private int mWidth = 1920;
    private int mHeight = 1080;
    private void startDecoding(InputStream inputStream) throws IOException {
        // 配置你的MediaCodec
        // 创建一个MediaFormat对象
        mediaFormat = new MediaFormat();
        // 设置视频格式的属性
        //KEY_MIME_TYPE：媒体类型的字符串表示，对于视频通常是video/avc（H.264）或video/hevc（H.265）
        mediaFormat.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_VIDEO_AVC);
        //KEY_COLOR_FORMAT：颜色格式的整数表示，如MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Flexible。
        mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Flexible);
        mediaFormat.setInteger(MediaFormat.KEY_WIDTH, mWidth); // 设置视频宽度
        mediaFormat.setInteger(MediaFormat.KEY_HEIGHT, mHeight); // 设置视频高度
        //KEY_BIT_RATE：比特率，单位为比特每秒（bps），表示每秒传送的比特数
        //mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, 5000000); // 设置比特率为5Mbps
        mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, mWidth * mHeight * 5);
        //KEY_FRAME_RATE：帧率，表示每秒显示的帧数，单位为帧每秒（fps）
        mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 30); // 设置帧率为30fps
        //KEY_I_FRAME_INTERVAL：I帧间隔，表示两个关键帧（I帧）之间的最大帧数。
        // 视频编码器会在视频中周期性地插入一个I帧，以便于视频的随机访问。
        mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 5); // 设置I帧间隔为5

        mediaCodec = MediaCodec.createDecoderByType(mediaFormat.getString(MediaFormat.KEY_MIME));
        Surface surface = surfaceHolder.getSurface();
        mediaCodec.configure(mediaFormat, surface, null, 0);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            mediaCodec.setOutputSurface(surface);
        }
        mediaCodec.start();
        // 从inputStream中读取数据并送给MediaCodec解码
        while (!Thread.currentThread().isInterrupted()) {
            try {
                /**
                 * 延迟 TIME_US 等待拿到空的 input buffer下标，单位为 us
                 * -1 表示一直等待，知道拿到数据，0 表示立即返回
                 */
                int inputBufferIndex = mediaCodec.dequeueInputBuffer(-1);
                if (inputBufferIndex >= 0) {
                    ByteBuffer inputBuffer = mediaCodec.getInputBuffer(inputBufferIndex);
                    // 读取数据到缓冲区
                    byte[] buffer = new byte[inputBuffer.remaining()];
                    int bytesRead = inputStream.read(buffer);
                    /****
                     *
                     *
                    String videoHex=CommonUtil.bytesToHexString(buffer,false);
                    String currentFrameHex=videoHex.substring(0,4);
                    int currentFrame= Integer.parseInt(currentFrameHex, 16);
                    videoHex=videoHex.substring(4,(currentFrame*2));
                    videoHex=videoHex.substring(28,videoHex.length());
                    buffer=CommonUtil.hexStringToBytes(videoHex);
                    bytesRead = inputStream.read(buffer);

                     */
                    if (bytesRead == -1) {
                        // 如果到达流的末尾，发送EOS
                        mediaCodec.queueInputBuffer(inputBufferIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
                        break;
                    } else {
                        // 将读取的数据放入缓冲区
                        inputBuffer.put(buffer, 0, bytesRead);
                        // 提交缓冲区到解码器
                        mediaCodec.queueInputBuffer(inputBufferIndex, 0, bytesRead, 0, 0);
                    }
                }

                // 处理解码后的输出缓冲区
                MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
                int outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, 0);
                while (outputBufferIndex >= 0) {
                    // 如果输出缓冲区有效，渲染到Surface
                    mediaCodec.releaseOutputBuffer(outputBufferIndex, true);
                    outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, 0);
                }

                // 如果解码器输出缓冲区标志为EOS，则停止解码
                if ((bufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
                    break;
                }
            } catch (IOException e) {
                e.printStackTrace();
                break;
            }
        }
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        // 当Surface被创建后，你可以开始接收视频流并解码
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        // Surface大小改变时的处理
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        // 停止解码器并释放资源
        if(mediaCodec!=null) {
            mediaCodec.stop();
            mediaCodec.release();
        }

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        try {
            if(serverSocket!=null){
                serverSocket.close();
                serverSocket=null;
            }
        }catch (Exception ex){

        }
    }

}